package com.dbsync.core;

import com.dbsync.exception.DbsyncException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 数据库适配器类
 */
public class DBAdapter {
    private static Map<String, List<String>> foreignSqlMap = new HashMap<>();

    public static void clearForeignSqlMap(){
        foreignSqlMap.clear();
    }

    /**
     * 获取对应类型的数据表查询语句
     * @param dbUtil 数据库工具
     * @return 返回数据表查询语句
     * @throws DbsyncException
     */
    public static String getQueryAllTableSQL(DBUtil dbUtil) throws DbsyncException{
        if ("mysql".equalsIgnoreCase(dbUtil.getDBType(0))){
            StringBuilder sql = new StringBuilder();
            sql.append("SELECT TABLE_NAME AS name ")
                    .append("FROM information_schema.TABLES ")
                    .append("WHERE TABLE_TYPE='BASE TABLE' ")
                    .append("AND TABLE_SCHEMA='").append(dbUtil.getDBName()).append("'");
            return sql.toString();
        }else if ("oracle".equalsIgnoreCase(dbUtil.getDBType(0))){
            return "SELECT uo.object_name FROM user_objects uo WHERE uo.object_type = 'TABLE'";
        }else if ("sql server".equalsIgnoreCase(dbUtil.getDBType(0))){
            return "SELECT name FROM sysobjects";
        }else if ("sybase".equalsIgnoreCase(dbUtil.getDBType(0))){
            return "SELECT name FROM sysobjects WHERE type='U'";
        }else if ("db2".equalsIgnoreCase(dbUtil.getDBType(0))){
            return "SELECT tabname FROM syscat.tables WHERE tabschema = current SCHEMA";
        }else{
            throw new DbsyncException("未支持的数据库类型");
        }
    }

    /**
     * 获取对应类型的建表查询语句
     * @param dbUtil 数据库工具
     * @param tableName 表名称
     * @return 返回建表查询语句
     * @throws DbsyncException
     */
    public static String getQueryCreateTableSQL(DBUtil dbUtil, String tableName) throws DbsyncException{
        StringBuilder sql = new StringBuilder();
        if ("mysql".equalsIgnoreCase(dbUtil.getDBType(0))){
            sql.append("SHOW CREATE TABLE ").append(tableName);
        }else if ("oracle".equalsIgnoreCase(dbUtil.getDBType(0))){
            sql.append("SELECT DBMS_METADATA.GET_DDL(")
                .append("'TABLE','").append(tableName).append("','").append(dbUtil.getDBName())
                .append("') AS 'Create Table' ")
                .append("FROM DUAL ");
        }else if ("sql server".equalsIgnoreCase(dbUtil.getDBType(0))){
            sql.append("");
        }else if ("sybase".equalsIgnoreCase(dbUtil.getDBType(0))){
            sql.append("");
        }else if ("db2".equalsIgnoreCase(dbUtil.getDBType(0))){
            sql.append("");
        }else{
            throw new DbsyncException("未支持的数据库类型");
        }
        return sql.toString();
    }

    public static String getCreateTableSQL(DBUtil dbUtil, int targetIndex, String tableName, String sql) throws DbsyncException{
        StringBuilder createSql = new StringBuilder();
        if ("mysql".equalsIgnoreCase(dbUtil.getDBType(targetIndex))){
            if (sql.contains("FOREIGN KEY")){
                List<String> foreignSqlList = new ArrayList<>();
                Pattern pattern = Pattern.compile("CONSTRAINT[\\s\\S]+?\\n");
                Matcher matcher = pattern.matcher(sql);
                while (matcher.find()){
                    StringBuilder foreignSql = new StringBuilder();
                    foreignSql.append("ALTER TABLE `").append(tableName).append("` ADD ").append(matcher.group().replace(",", ""));
                    foreignSqlList.add(foreignSql.toString());
                }
                foreignSqlMap.put(tableName, foreignSqlList);
            }
            createSql.append(sql.replaceAll("CONSTRAINT[\\s\\S]+?\\n|KEY `[\\s\\S]+` \\(`[\\s\\S]+`\\).*?\\n", "").replace("),", ")"));
        }else if ("oracle".equalsIgnoreCase(dbUtil.getDBType(0))){
            createSql.append("");
        }else if ("sql server".equalsIgnoreCase(dbUtil.getDBType(0))){
            createSql.append("");
        }else if ("sybase".equalsIgnoreCase(dbUtil.getDBType(0))){
            createSql.append("");
        }else if ("db2".equalsIgnoreCase(dbUtil.getDBType(0))){
            createSql.append("");
        }else{
            throw new DbsyncException("未支持的数据库类型");
        }
        return createSql.toString();
    }

    public static String getClearTableSQL(DBUtil dbUtil, int targetIndex, String tableName) throws DbsyncException{
        StringBuilder clearSql = new StringBuilder();
        if ("mysql".equalsIgnoreCase(dbUtil.getDBType(targetIndex))){
            clearSql.append("DROP TABLE IF EXISTS `").append(tableName).append("`");
        }else if ("oracle".equalsIgnoreCase(dbUtil.getDBType(0))){
            clearSql.append("");
        }else if ("sql server".equalsIgnoreCase(dbUtil.getDBType(0))){
            clearSql.append("");
        }else if ("sybase".equalsIgnoreCase(dbUtil.getDBType(0))){
            clearSql.append("");
        }else if ("db2".equalsIgnoreCase(dbUtil.getDBType(0))){
            clearSql.append("");
        }else{
            throw new DbsyncException("未支持的数据库类型");
        }
        return clearSql.toString();
    }

    public static List<String> getforeignSqlList(String tableName){
        return foreignSqlMap.get(tableName);
    }
}
